package com.block.channelext.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.block.channelext.enums.ActionTypeEnum;
import com.block.channelext.enums.ChannelEnum;
import com.block.channelext.factory.ActionTypeFactory;
import com.block.channelext.model.result.ReportResult;
import com.block.channelext.service.IActionHandleService;
import com.block.channelext.service.IActionInfoService;
import com.block.channelext.service.IChannelActionReportService;
import com.block.common.bean.CommonParam;
import com.block.common.exception.NotifyExceptionService;
import com.block.common.service.IChannelCommonService;
import com.block.common.service.LogFactory;
import com.block.db.entity.ChannelActionReport;
import com.block.db.entity.ChannelInfo;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDate;

@Service
public class ActionInfoService implements IActionInfoService {

    private static Logger log = LogFactory.getCommLog();

    @Autowired
    NotifyExceptionService notifyExceptionService;
    @Autowired
    IChannelCommonService channelCommonService;
    @Autowired
    IChannelActionReportService channelActionReportService;

    /**
     * 一些操作之后，需要进行的操作
     * 1。极准操作上报
     * @param channelCode
     * @param actionTypeEnum
     * @param commonParam
     */
//    @Async
    @Override
    public void actionHandle(String channelCode, ActionTypeEnum actionTypeEnum, CommonParam commonParam, Long uid){

        try {
            JSONObject extJson = JSON.parseObject(JSON.toJSONString(commonParam));

            /**
             * 判断渠道是否需要处理
             */
            if (!ChannelEnum.contains(channelCode)){
                log.info("【渠道上报】渠道枚举不存在【channelCode】{}", channelCode);
                return;
            }

            /**
             * 根据渠道比率
             */
            ChannelInfo channelInfoCache = channelCommonService.getChannelInfoCache(channelCode);
            if (ObjectUtil.isEmpty(channelInfoCache)){
                log.info("【渠道上报】渠道信息不存在【channelCode】{}", channelCode);
                return;
            }

            BigDecimal channelRate = channelInfoCache.getChannelRate();
            BigDecimal randomNumber = new BigDecimal(RandomUtil.randomDouble(1));
            if (randomNumber.compareTo(channelRate) >= 0){
                //0-rate 的进行上报
                log.info("【渠道上报】上报率不满足【channelCode】{}【randomNumber】{}【channelRate】{}", channelCode, randomNumber, channelRate );
                return;
            }

            IActionHandleService actionHandleService = ActionTypeFactory.getService(actionTypeEnum.getValue());
            if (ObjectUtil.isEmpty(actionHandleService)){
                return;
            }

            ChannelActionReport actionReport = new ChannelActionReport();
            actionReport.setDateInfo(LocalDate.now().toString());
            actionReport.setChannelCode(channelInfoCache.getChannelCode());
            actionReport.setChannelName(channelInfoCache.getChannelName());
            actionReport.setType(actionTypeEnum.getType());
            actionReport.setStatus("INIT");
            actionReport.setUid(uid);
            channelActionReportService.save(actionReport);
            ReportResult reportResult = actionHandleService.actionTypeHandle(channelInfoCache, extJson);
            log.info("【渠道上报结果】【reportResult】{}", JSON.toJSONString(reportResult));

            if (ObjectUtil.isNotEmpty(reportResult)){
                ChannelActionReport updateEntity = new ChannelActionReport();
                updateEntity.setId(actionReport.getId());

                if (reportResult.isSuccess()){
                    updateEntity.setStatus("SUCCESS");
                }else {
                    updateEntity.setStatus("FAILED");
                }

                updateEntity.setResultCode(reportResult.getCode());
                updateEntity.setResultMessage(reportResult.getMessage());
                updateEntity.setParamInfo(reportResult.getParamInfo());
                updateEntity.setResultInfo(reportResult.getResultInfo());
                channelActionReportService.updateById(updateEntity);
            }
        }catch (Exception exception){
            exception.printStackTrace();
            log.error("【渠道上报操作异常】【channelCode】{}", channelCode);
            notifyExceptionService.notifyException("", "", "", "【渠道上报操作异常】", exception);
        }
    }

}
